package com.ifar.audiosdk.api

import com.google.gson.Gson
import com.ifar.audiosdk.common.IfarConfig
import com.ifar.audiosdk.common.entity.IfarMsgData
import com.ifar.audiosdk.common.entity.IfarRecorderEntity
import com.ifar.audiosdk.common.entity.IfarWebSocketEntity
import com.orhanobut.logger.Logger
import okhttp3.*
import java.util.concurrent.TimeUnit

object IfarWebSocketManager {
    private lateinit var mClient: OkHttpClient
    private lateinit var mWebSocket: WebSocket
    private lateinit var mWsListener: WsListener
    private const val timeOut = 30L

    private var wsUrl = ""

    interface WsListener {
        fun wsOpen()
        fun wsClose()
        fun wsMessage(msg: String)
    }

    class SocketListener : WebSocketListener() {
        override fun onOpen(webSocket: WebSocket, response: Response) {
            mWsListener.wsOpen()
        }

        override fun onMessage(webSocket: WebSocket, text: String) {
            mWsListener.wsMessage(text)
        }

        override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
            mWsListener.wsClose()
        }
    }

    fun connect(wsListener: WsListener) {
        Logger.e("connect-------")
        try {
            mClient = OkHttpClient.Builder()
                .readTimeout(timeOut, TimeUnit.SECONDS)//设置读取超时时间
                .writeTimeout(timeOut, TimeUnit.SECONDS)//设置写的超时时间
                .connectTimeout(timeOut, TimeUnit.SECONDS)//设置连接超时时间
                .retryOnConnectionFailure(true)//断线重连
                .build()

            wsUrl = IfarConfig.WS_BASE + IfarConfig.ws_port +
                    "?signID=" + IfarConfig.sign_id +
                    "&fromID=" + IfarConfig.id +
                    "&companyID=" + IfarConfig.company_id +
                    "&time=" + System.currentTimeMillis()

            val request: Request = Request.Builder()
                .url(wsUrl)
                .build()

            mWsListener = wsListener

            mWebSocket = mClient.newWebSocket(request, SocketListener())
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    private fun sendMessage(webSocketEntity: IfarWebSocketEntity) {
        val json: String = Gson().toJson(webSocketEntity)
        mWebSocket.send(json)
    }

    private fun sendCommonMsg(
        toID: String, toName: String = "", msgMainFlag: String, msgSubFlag: String = ""
    ) {
        sendMessage(
            IfarWebSocketEntity(
                toID = toID, toName = toName, msgMainFlag = msgMainFlag, msgSubFlag = msgSubFlag
            )
        )
    }

    /**
     * 登录后更新用户属性数据
     */
    fun setUserAtts() {
        sendCommonMsg(toID = "0", msgMainFlag = "SetAtts")
    }

    fun setUserChannelId() {
        sendCommonMsg(toID = "0", msgMainFlag = "SetAtts")
    }

    private fun updateUserList() {
        sendCommonMsg(
            toID = "0", msgMainFlag = "NotifyUpdateUserList", msgSubFlag = "UpdateUserList"
        )
    }

    fun loginOut() {
        sendCommonMsg(toID = "0", msgMainFlag = "Login", msgSubFlag = "LoginOut")
    }

    fun closeMarkBg() {
        sendCommonMsg(toID = "-2", msgMainFlag = "ChannelChat", msgSubFlag = "CloseMark")
    }

    fun closeMarkPdf() {
        sendCommonMsg(toID = "-2", msgMainFlag = "ChannelChat", msgSubFlag = "ClosePDF")
    }

    fun closeMarkVideo() {
        sendCommonMsg(toID = "-2", msgMainFlag = "ChannelChat", msgSubFlag = "CloseVideo")
    }

    //本地禁音
    fun mutedAudio() {
        sendCommonMsg(toID = "-2", msgMainFlag = "ChannelChat", msgSubFlag = "MutedAudio")
    }

    //本地取消禁音
    fun unmutedAudio() {
        sendCommonMsg(toID = "-2", msgMainFlag = "ChannelChat", msgSubFlag = "MutedAudio")
    }

    //录制结束
    fun recorderStop(recorderInfo: IfarRecorderEntity) {
        sendMessage(
            IfarWebSocketEntity(
                toID = "-2", msgMainFlag = "ChannelChat", msgSubFlag = "ArchiveVideo",
                msgData = IfarMsgData(
                    url = recorderInfo.video_url,
                    file_name = recorderInfo.save_name,
                    file_size = recorderInfo.file_size
                )
            )
        )
    }

    fun requestHeart() {
        sendCommonMsg(toID = "0", msgMainFlag = "Heart")
    }

    fun requestCallOffer(userId: String, userName: String) {
        sendCommonMsg(
            toID = userId, toName = userName, msgMainFlag = "CallOffer", msgSubFlag = "Request"
        )
        updateUserList()
    }

    fun requestCallConnect(userId: String, userName: String) {
        sendCommonMsg(
            toID = userId, toName = userName, msgMainFlag = "CallAnswer", msgSubFlag = "Connect"
        )
        updateUserList()
        joinChannel()
    }

    fun requestCallAnswerHangup(userId: String, userName: String) {
        IfarConfig.channel_id = ""
        sendCommonMsg(
            toID = userId, toName = userName, msgMainFlag = "CallAnswer", msgSubFlag = "Hangup"
        )
        sendCommonMsg(toID = "0", msgMainFlag = "SetAtts")
        updateUserList()
    }

    fun leaveChannel() {
        sendCommonMsg(toID = "-2", msgMainFlag = "CallingMsg", msgSubFlag = "Hangup")
        IfarConfig.channel_id = ""
        sendCommonMsg(toID = "0", msgMainFlag = "SetAtts")
        updateUserList()
    }

    private fun joinChannel() {
        sendCommonMsg(toID = "-2", msgMainFlag = "Calling")
    }

    fun answerMarkBg(userId: String, url: String, userName: String) {
        sendMessage(
            IfarWebSocketEntity(
                toID = userId, toName = userName, msgMainFlag = "ChannelChat",
                msgSubFlag = "ArchiveVideo", msgData = IfarMsgData(url = url)
            )
        )
    }

    fun sendChatText(msg: String) {
        sendMessage(
            IfarWebSocketEntity(
                toID = "-2", msgMainFlag = "ChannelChat", msgSubFlag = "Text",
                msgData = IfarMsgData(value = msg)
            )
        )
    }

    fun sendChatImage(url: String) {
        sendMessage(
            IfarWebSocketEntity(
                toID = "-2", msgMainFlag = "ChannelChat", msgSubFlag = "ArchiveImage",
                msgData = IfarMsgData(url = url)
            )
        )
    }


}